(PYTHON) Day - 7 Strings(3)

Reference

  • 문제 출처 - HackerRank
  • 파이썬 연습 - Practice - Python

개인적인 생각과 상상으로 작성한 내용들이 포함되어 있습니다
문제를 풀고 Discussion Tab을 참고하며 코드 스타일을 개선하려고 노력하고자 합니다



HackerRank

HackerRank의 Python 연습문제들은 아래와 같은 카테고리로 분류 된다:

Subdomain

  • Introduction
  • Basic Data Types
  • Strings
  • Sets
  • Math
  • Itertools
  • Collections
  • Date and Time
  • Errors and Exceptions
  • Classes
  • Built-Ins
  • Python Functionals
  • Regex and Parsing
  • XML
  • Closures and Decorators
  • Numpy
  • Debugging


Strings

기본 개념

Text Alignment

다음 함수를 사용하여 문자열은 좌, 우, 중앙으로 정렬시킬 수 있다
width는 필수로 입력해야하고 공백을 채울 문자(fillchar)는 선택적으로 입력, 기본값은 space
str.ljust(width[, fillchar]) : 왼쪽 정렬
str.center(width[, fillchar]) : 오른쪽 정렬
str.rjust(width[, fillchar]) : 가운데 정렬

5

    H    
   HHH   
  HHHHH  
 HHHHHHH
HHHHHHHHH
  HHHHH               HHHHH             
  HHHHH               HHHHH             
  HHHHH               HHHHH             
  HHHHH               HHHHH             
  HHHHH               HHHHH             
  HHHHH               HHHHH             
  HHHHHHHHHHHHHHHHHHHHHHHHH   
  HHHHHHHHHHHHHHHHHHHHHHHHH   
  HHHHHHHHHHHHHHHHHHHHHHHHH   
  HHHHH               HHHHH             
  HHHHH               HHHHH             
  HHHHH               HHHHH             
  HHHHH               HHHHH             
  HHHHH               HHHHH             
  HHHHH               HHHHH             
                   HHHHHHHHH
                    HHHHHHH  
                     HHHHH   
                      HHH    
                       H  

Cone, Pillars, Belt 부분으로 나누어서 그림을 그려나가는 것이 흥미로웠다
아래 코드는 해당 문제를 풀때 Editor에 자동으로 입력되어 있던 코드에서 ljust, rjust, center 함수만 끼워 넣은 것이다

#Replace all **\_\_** with rjust, ljust or center.

thickness = int(input()) #This must be an odd number
c = 'H'

#Top Cone
for i in range(thickness):
print((c*i).rjust(thickness-1)+c+(c*i).ljust(thickness-1))

#Top Pillars
for i in range(thickness+1):
print((c*thickness).center(thickness*2)+(c*thickness).center(thickness*6))

#Middle Belt
for i in range((thickness+1)//2):
print((c*thickness*5).center(thickness\*6))

#Bottom Pillars
for i in range(thickness+1):
print((c*thickness).center(thickness*2)+(c*thickness).center(thickness*6))

#Bottom Cone
for i in range(thickness):
print(((c*(thickness-i-1)).rjust(thickness)+c+(c*(thickness-i-1)).ljust(thickness)).rjust(thickness\*6))
  • 재사용성을 생각했을 때, 각 부분들을 정의해 놓고 마지막에 출력할 때 필요한 부분들을 블럭을 조립하듯이 쌓으면 훨씬 깔끔한 것 같다
width =int(input())
c='H'

top_cone = [(c*(2*i+1)).center(2*width) for i in range(width)]
pillars = [(c*width + ' ' * 3 * width + c * width).center(6*width) for _ in range(width+1)]
base = [(c*5*width).center(6*width) for _ in range(width/2+1)]
bottom_cone = [r.rjust(6*width) for r in cone[::-1]]

print('\n'.join(top_cone + pillars + base + pillars + bottom_cone))

Text Wrap

문제 : 입력되는 문자열 S를 길이 w만큼 잘라서 출력
예제 : ‘ABCDEFGHIJKLIMNOQRSTUVWXYZ’를 4개씩 잘라서 ‘ABCD’, ‘EFGH’, … 로 출력

ABCDEFGHIJKLIMNOQRSTUVWXYZ
4

ABCD
EFGH
IJKL
IMNO
QRST
UVWX
YZ

import time
import textwrap

def wrap(string, max_width):
return '\n'.join([string[i:i+max_width] for i in range(0, len(string), max_width)])

def text_wrap(string, max_width):
return '\n'.join(textwrap.wrap(string, max_width))

if **name** == '**main**':
string, max_width = input(), int(input())

start_1 = time.time()
result = wrap(string, max_width)
end_1 = time.time()

start_2 = time.time()
result_2 = text_wrap(string, max_width)
end_2 = time.time()

print(result, result == result_2, sep='\n')
print('list_comprehension: '.ljust(20), round((end_1 - start_1) * 100, 8))
print('textwrap: '.ljust(20), round((end_2 - start_2) * 100, 8))
  • 7배 정도 느린데 굳이 textwrap 모듈을 사용해야 할까?

# input

ABCDEFGHIJKLIMNOQRSTUVWXYZ
4

# output

ABCD
EFGH
IJKL
IMNO
QRST
UVWX
YZ
True
list_comprehension: 0.00259876
textwrap: 0.01468658

Designer Door Mat

문제 : 예제와 같은 NxM 크기의 디자인 패턴을 그리는 문제(가운데 welcome, 패턴에는 -, |, . 세개만 사용, N은 홀수이고 M의 크기는 N의 3배)
예제 : 디자인 패턴 참고

9 27

  ------------.|.------------
  ---------.|..|..|.---------
  ------.|..|..|..|..|.------
  ---.|..|..|..|..|..|..|.---
  ----------WELCOME----------
  ---.|..|..|..|..|..|..|.---
  ------.|..|..|..|..|.------
  ---------.|..|..|.---------
  ------------.|.------------

Text Alignment 문제의 아이디어를 응용하여 패턴과 가운데 글자를 하나의 데이터로 정의하여 풀었음

if **name** == '**main**':
N, M = map(int, input().split())
pattern = [('.|.' * (2*i+1)).center(M, '-') for i in range(N//2)]
middle_pattern = 'WELCOME'.center(M, '-')

print('\n'.join(pattern), middle_pattern, '\n'.join(pattern[::-1]), sep='\n')

Alphabet Rangoli

문제 : Rangoli는 인도의 전통미술 패턴이다. 입력받는 N 크기의 랑골리 패턴을 그리는 문제
예제 : 랑골리 패턴 참고(크기가 커질수록 알파벳순으로 글자도 늘어남)

5

  --------e--------
  ------e-d-e------
  ----e-d-c-d-e----
  --e-d-c-b-c-d-e--
  e-d-c-b-a-b-c-d-e
  --e-d-c-b-c-d-e--
  ----e-d-c-d-e----
  ------e-d-e------
  --------e-------- 
import string

def print_rangoli(size):
alpha = string.ascii_lowercase
L = []
for i in range(n):
s = "-".join(alpha[i:n])
L.append((s[::-1]+s[1:]).center(4\*n-3, "-"))

print('\n'.join(L[:0:-1]+L))

if **name** == '**main**':
n = int(input())
print_rangoli(n)